/// 
/// Author: Jeff Liu
/// Date: 2023-05-05 16:46:15
/// LastEditTime: 2023-06-26 09:50:08
/// LastEditors: Jeff Liu
/// Description: 
/// FilePath: /CCH/src/cls/HCC/SVR/Prod/BP/MainControlGeneral.cls
/// Jeff.liu@intersytems.com
/// 
/// General总控流程
Class HCC.SVR.Prod.BP.MainControlGeneral Extends Ens.BusinessProcessBPL [ DependsOn = HCC.SVR.Prod.BP.Context ]
{

/// 结构验证设置
Property MsgSchemaValidate As %Boolean [ InitialExpression = 0 ];

/// 值集验证设置
Property MsgValueSetValidate As %Boolean [ InitialExpression = 0 ];

/// 同步消息超时时间设置单位秒
/// 
Property SyncTimeOutSeconds As %Integer [ InitialExpression = 10 ];

/// 消息 schema 文件夹路径
Property SchemaFolder As %String(MAXLEN = "") [ InitialExpression = {..SetSaveMsgSchemaFolder()} ];

Parameter SETTINGS = "MsgSchemaValidate:Basic,MsgValueSetValidate:Basic,SchemaFolder:Basic:directorySelector,SyncTimeOutSeconds:Basic";

ClassMethod SetSaveMsgSchemaFolder() As %String
{
    set installPath= ##class(%SYSTEM.Util).InstallDirectory()
    set wPath= installPath_"lib\HCC\MSGSchema\multicacheschemas\"
    set uPath= installPath_"lib/HCC/MSGSchema/multicacheschemas/"
    //2 for Windows, 3 for UNIX®, and 0 if not known.
    set os=$ZVERSION(1)
    return $CASE(os,2: wPath,3: uPath,0: "")
}


/// BPL Definition
XData BPL [ XMLNamespace = "http://www.intersystems.com/bpl" ]
{
<process language='objectscript' request='HCC.SVR.Prod.MSG.SVRRequest' response='HCC.SVR.Prod.MSG.SVRResponse' contextsuperclass='HCC.SVR.Prod.BP.Context' height='3900' width='2000' >
<context>
<property name='verifyResult' type='%Boolean' initialexpression='0' instantiate='0' />
<property name='tResponse' type='HCC.SVR.Prod.MSG.SVRResponse' instantiate='1' />
<property name='action' type='%String' instantiate='0' >
<parameters>
<parameter name='MAXLEN'  value='50' />
</parameters>
</property>
<property name='tDocType' type='%String' instantiate='0' >
<parameters>
<parameter name='MAXLEN'  value='50' />
</parameters>
</property>
<property name='ErrMsg' type='%String' instantiate='0' >
<parameters>
<parameter name='MAXLEN'  value='' />
</parameters>
</property>
<property name='valueVerifyResult' type='%Boolean' initialexpression='0' instantiate='0' />
<property name='valueErrMsg' type='%String' instantiate='0' >
<parameters>
<parameter name='MAXLEN'  value='' />
</parameters>
</property>
<property name='SchemaValidateOption' type='%Boolean' instantiate='0' />
<property name='ValuseSetValidateOption' type='%Boolean' instantiate='0' />
<property name='IfSync' type='%String' instantiate='0' >
<parameters>
<parameter name='MAXLEN'  value='50' />
</parameters>
</property>
</context>
<sequence xend='200' yend='2650' >
<scope xpos='200' ypos='250' xend='200' yend='2550' >
<code name='获取同步超时时间' xpos='200' ypos='350' >
<![CDATA[ set context.TimeOutSeconds =##class(Ens.Director).GetHostSettingValue(context.pProductionName_"||HCC.SVR.Prod.BP.MainControlGeneral","SyncTimeOutSeconds",.tSC)+1]]>
</code>
<trace name='追踪超时设置时间' value='context.TimeOutSeconds' xpos='200' ypos='450' />
<code name='写入服务调用log' xpos='200' ypos='550' >
<![CDATA[ set sTS=..%Process.%PrimaryRequestHeader.TimeCreated
 set sTS= $zdt($System.Util.UTCtoLocalWithZTIMEZONE($zdth(sTS,3)),3)
 do ##class(HCC.Util).HCCSvrLog(request.Action,..%Process.%PrimaryRequestHeader.%Id(),sTS)]]>
</code>
<trace name='追踪请求创建时间' value='..%Process.%PrimaryRequestHeader.TimeCreated' xpos='200' ypos='650' />
<sql name='LT获得action 对应schema' xpos='200' ypos='750' >
<![CDATA[
SELECT SchemaType INTO :context.tDocType FROM HCC_SVR_PubSub.Topic WHERE 
 TopicName=:request.Action]]>
</sql>
<if name='判断action和schema是否对应' condition='request.DocType=context.tDocType' xpos='200' ypos='850' xend='200' yend='1550' >
<true>
<code name='判断消息体结构合规性' xpos='470' ypos='1000' >
<![CDATA[ Set val=##class(Ens.Director).GetHostSettingValue(context.pProductionName_"||HCC.SVR.Prod.BP.MainControlGeneral","MsgSchemaValidate",.tSC) 
 set schemalocation =##class(Ens.Director).GetHostSettingValue(context.pProductionName_"||HCC.SVR.Prod.BP.MainControlGeneral","SchemaFolder",.tSC) 
  if (val=1) {
 Set tSchema="urn:hl7-org:v3 "_schemalocation_request.DocType_".xsd"	
 Set tSC=##class(%XML.TextReader).ParseStream(request.Message,.tReader,,,,tSchema)
 set context.verifyResult=0	
 set errCount=0
 While (tReader.Read()) 	
  {		
	if (tReader.NodeType="error") 		
	{		set errCount= errCount+1
		set context.ErrMsg= context.ErrMsg_"*ERROR* "_tReader.Value_$char(10)_tReader.Path_$char(10)	
		$$$TRACE(context.ErrMsg)	
	}	
  }	
  if (errCount=0)
  {
  set context.verifyResult=1
  }
  }
  else{set context.verifyResult=1}]]>
</code>
<code name='判断消息体值集合规性' xpos='470' ypos='1100' >
<![CDATA[  set msg=""
  Set val=##class(Ens.Director).GetHostSettingValue(context.pProductionName_"||HCC.SVR.Prod.BP.MainControlGeneral","MsgValueSetValidate",.tSC) 
  if (val=1) 
  {set context.valueVerifyResult=##class(HCC.Utils.XMLValid).ValidDocsValueRange(request.Message,"",.msg)
  set context.valueVerifyResult=val&&context.valueVerifyResult
  set context.valueErrMsg=msg}
  else
  {
  set context.valueVerifyResult =1
  }]]>
</code>
<if name='判断合规结果' condition='(context.verifyResult =1)&amp;&amp;(context.valueVerifyResult=1)' xpos='470' ypos='1200' xend='470' yend='1450' >
<true>
<call name='订阅发布' target='HCC.SVR.Prod.BP.SubscribeAndPublishGeneral' async='1' xpos='740' ypos='1350' >
<request type='HCC.SVR.Prod.MSG.SVRRequest' >
<assign property="callrequest" value="request" action="set" />
</request>
<response type='HCC.SVR.Prod.MSG.SVRResponse' >
<assign property="context.tResponse" value="callresponse" action="set" />
</response>
</call>
</true>
<false>
<code name='不合规' xpos='470' ypos='1350' >
<![CDATA[ set context.tResponse= ##class(HCC.Utils.ResponseHelper).ReturnErrorMsgNoSenderInfo(context.action,"消息不合规"_$Char(10)_context.ErrMsg_context.valueErrMsg)]]>
</code>
</false>
</if>
</true>
<false>
<code name='action 和 schema 不对应' xpos='200' ypos='1000' >
<![CDATA[ set context.tResponse= ##class(HCC.Utils.ResponseHelper).ReturnErrorMsgNoSenderInfo(context.action,"操作和schema类型不对应")]]>
</code>
</false>
</if>
<trace name='追踪错误信息' value='context.tDocType_"   "_request.DocType_"   "_context.verifyResult_"   "_context.valueVerifyResult_"   "_context.ErrMsg_" "_context.valueErrMsg' xpos='200' ypos='1650' />
<sync name='等待返回消息' calls='订阅发布' timeout='context.TimeOutSeconds' type='any' xpos='200' ypos='1750' />
<if name='处理超时' condition='synctimedout =0' xpos='200' ypos='1850' xend='200' yend='2100' >
<false>
<code name='生成超时返回消息' xpos='335' ypos='2000' >
<![CDATA[ set context.tResponse= ##class(HCC.Utils.ResponseHelper).ReturnErrorMsgNoSenderInfo(request.MsgId,"消息处理超时"_$char(10)_context.ErrMsg)]]>
</code>
</false>
</if>
<trace name='追踪同步超时时间' value='synctimedout_context.TimeOutSeconds' xpos='200' ypos='2200' />
<assign name="返回标准消息" property="response" value="context.tResponse" action="set" xpos='200' ypos='2300' />
<faulthandlers>
<catchall xpos='200' ypos='2400' xend='200' yend='550' >
<trace value='"%LastError "_ $System.Status.GetErrorCodes(..%Context.%LastError)_ " : "_ $System.Status.GetOneStatusText(..%Context.%LastError)' xpos='200' ypos='250' />
<code xpos='200' ypos='350' >
<![CDATA[ set context.tResponse= ##class(HCC.Utils.ResponseHelper).ReturnErrorMsgNoSenderInfo(request.MsgId,"平台内部异常."_ $System.Status.GetErrorCodes(..%Context.%LastError)_ " : "_ $System.Status.GetOneStatusText(..%Context.%LastError))]]>
</code>
<assign property="response" value="context.tResponse" action="set" xpos='200' ypos='450' />
</catchall>
</faulthandlers>
</scope>
</sequence>
</process>
}

}
